<?php
/**
 * Created by PhpStorm.
 * User: Dave
 * Date: 2018/3/16
 * Time: 17:04
 */

namespace Biz\service\trade;

use Biz\model\trade\OrderLogistics as mOrderLogistics;
use Biz\module\Packages\Logistics\CourierBird as mdlCourierBird;
use Biz\module\Packages\Logistics\TrackingMore as mdlTrackingMore;
use Biz\model\trade\Order as mOrder;
use Biz\pockets\serviceTrait\_Async;
use Doraemon\tools\Log as tLog;
use Biz\model\trade\OrderPackage as mOrderPackage;
use Biz\module\Classes\OrderInfo as clsOrderInfo;
use Biz\module\Packages\CustomerService\SmallEnergy;
use Doraemon\tools\HhzClient as tHhzClient;

/**
 *
 * 快递查询service
 **/

class Logistics
{

    const LOGISTICS_WAY_COURIERBIRD = 'courierbird';
    const LOGISTICS_WAY_TRACKINGMORE = 'trackingmore';
    use _Async;

    /**
     * app 查询快递物流
     * @param $uid
     * @param $orderNo
     * @param int $packageId
     * @return array|object
     * @throws \Exception
     */
    public static function orderTrack($uid, $orderNo, $packageId = 0)
    {
        $orderInfo = mOrder::getOrderInfo($orderNo, $uid);
        if (empty($orderInfo)) {
            return [];
        }

        if ($packageId == 0) {
            if ($orderInfo['is_package_delivery'] == mOrder::IS_PACKAGE_DELIVERY_YES) {
                $packageInfo = mOrderPackage::getFirstPackageInfo($orderNo);

                $packageId = $packageInfo['id'];
            }
        }

        $data = self::trackingmore($orderNo, $packageId);

        if (version_compare(tHhzClient::getClientVersion(), '3.19.0', '>=')) {
            if(count($data['content']) == 1) {
                $data['content'] = [];
                if(!$data['courier_website'] && !$data['courier_telephone']) {
                    $smallEnergyInfo = SmallEnergy::getSmallEnergyInfoByShopId($data['shop_id']);
                    $data['se_group_id'] = $smallEnergyInfo['pre_sale_reception_group_id'];
                }
            }
        }

        return $data;
    }

    /**
     * 接收第三方回调信息
     * @param $callBackData
     * @param $logisticsWay
     * @return false|string
     */
    public static function notifyCallBack($callBackData, $logisticsWay)
    {
        if ($logisticsWay == self::LOGISTICS_WAY_COURIERBIRD) {
            $result = mdlCourierBird::logisticsCallBack($callBackData);
            return $result;
        } else if ($logisticsWay == self::LOGISTICS_WAY_TRACKINGMORE) {
            mdlTrackingMore::logisticsCallBack($callBackData);
        }
    }

    /**
     * trackingmore查询物流
     * @param $orderNo
     * @param int $packageId
     * @return array|object
     * @throws \Exception
     */
    public static function trackingmore($orderNo, $packageId = 0)
    {
        return mdlTrackingMore::getLogistics($orderNo, $packageId);
    }

    /**
     * 商城tab5页面的快递信息
     * @param $uid
     * @return array|mixed
     */
    public static function getMultiLogistics($uid)
    {
        $lastLogistics = [];
        $orderNos = mOrder::getOrderInfoList(['uid' => $uid, 'status' => [mOrder::STATUS_SEND_OUT, mOrder::STATUS_SEND_PART_OUT]], [], [], false, 'order_no');
        $orderCount = $orderNos ? count($orderNos) : 0;
        $orderLogisticsData = mOrderLogistics::getMultiOrderLogistics(['order_no', 'logistics_info', 'addtime', 'package_id'], $uid, $orderNos);

        if (!empty($orderLogisticsData)) {
            $data = [];
            foreach ($orderLogisticsData as $k => $v) {
                $logisticsData = $v['logistics_info'] ? self::arraySort(json_decode($v['logistics_info'], true)) : [];
                $data[$k] = self::addKeyToContent($logisticsData, $v['addtime']);
                $data[$k]['order_no'] = $v['order_no'];
                $data[$k]['package_id'] = $v['package_id'];
            }

            $data = self::multiSort($data);
            $orderPackageLogistics = array_splice($data, 0, 2);
            $lastLogistics = array_map(function ($v) {
                $orderGoods = clsOrderInfo::getFirstSkuInfo($v['order_no'], $v['package_id']);
                $data = array_shift($v);
                $data['order_no'] = $v['order_no'];
                $data['package_id'] = $v['package_id'];
                $data['cover_img'] = $orderGoods['cover_img_thumb_url'];
                return $data;
            }, $orderPackageLogistics);
        }

        $data = [
            'list' => $lastLogistics ?: [],
            'count' => $orderCount,
        ];

        return $data;
    }

    /**
     * 查询最近的一条物流信息
     * @param $orderNo
     * @return mixed|null
     * @throws \Exception
     */
    public static function getLastLogisticsInfo($orderNo)
    {
        if (!empty($orderNo)) {
            $orderLogisticsList = mOrderLogistics::getOrdersLogistics(['logistics_info', 'addtime', 'package_id'], ['order_no' => $orderNo]);
            $orderLogisticsList = array_filter(array_map(function ($orderLogistics) {
                if (!empty($orderLogistics)) {
                    $logisticsInfo = $orderLogistics['logistics_info'] ? json_decode($orderLogistics['logistics_info'], true) : [];
                } else {
                    return null;
                }
                $logisticsInfo = self::arraySort($logisticsInfo);
                $logisticsInfo = self::addKeyToContent($logisticsInfo, $orderLogistics['addtime']);
                $logisticsInfo = array_shift($logisticsInfo);

                if (!empty($logisticsInfo)) {
                    $logisticsInfo['package_id'] = $orderLogistics['package_id'];
                }
                return $logisticsInfo;

            }, $orderLogisticsList));

            if (empty($orderLogisticsList)) {
                return null;
            }

            $acceptTimes = array_map(function ($v) {
                return strtotime($v);
            }, array_column($orderLogisticsList, 'accept_time'));

            array_multisort($acceptTimes, SORT_DESC, SORT_NUMERIC, $orderLogisticsList);
            return array_shift($orderLogisticsList);
        } else {
            throw new \Exception('订单号不能为空');
        }
    }


    /**
     * 向第三方发起订阅
     * @param $orderData
     */
    public static function subscribe($orderData)
    {
        self::_async($orderData);
    }

    public static function _async_subscribe($orderData)
    {
        try {

            $expressNo = self::getOrderLogisticsData(['express_no' => $orderData['express_no']], ['express_no']);
            self::addToLogistics($orderData);

            if (!$expressNo && $orderData['courierbird_code'] != 'shsm') {
                if ($orderData['trackingmore_code'])  {
                    $result = mdlTrackingMore::subscribe($orderData);
                    if ($result['meta']['code'] != 200 && !$result['meta']['type']) {
                        tLog::order_logistics_notice('trackingmore创建追踪失败 原因:' . $result['meta']['message'], ['orderData' => $orderData]);
                    } else {
                        tLog::order_logistics_info('trackingmore订阅成功', ['orderData' => $orderData]);
                    }
                }

                if ($orderData['courierbird_code']) {
                    $result = mdlCourierBird::subscribe($orderData);
                    if (!$result['json']['Success']) {
                        tLog::order_logistics_notice('快递鸟订阅失败 原因:' . $result['json']['Reason'], ['orderData' => $orderData]);
                    } else {
                        tLog::order_logistics_info('快递鸟订阅成功', ['orderData' => $orderData]);
                    }
                }
            }

            return true;
        } catch (\Exception $e) {

            tLog::order_logistics_notice('订阅失败', [
                'orderData' => $orderData,
                'e_msg' => $e->getMessage(),
                'e_file' => $e->getFile(),
                'e_line' => $e->getLine()
            ]);
            return false;
        }
    }

    /**
     * 基础信息入库
     * @param $orderData
     * @return mixed
     */
    public static function addToLogistics($orderData)
    {
        $orderInfo = self::getOrderLogisticsData(['order_no' => $orderData['order_no'], 'package_id' => $orderData['package_id']], ['order_no']);
        if ($orderInfo) {
            $result = mOrderLogistics::updateLogistics(['order_no' => $orderData['order_no'], 'package_id' => $orderData['package_id']],
                [
                    'express_no' => $orderData['express_no'],
                    'courierbird_code' => $orderData['courierbird_code'],
                    'trackingmore_code' => $orderData['trackingmore_code'],
                    'logistics_info' => '',
                    'edittime' => date('Y-m-d H:i:s'),
                ]
            );

        } else {
            $result = mOrderLogistics::insertLogistics($orderData);
        }

        return $result;
    }

    public static function getOrderLogisticsData($where, $field = '*')
    {
        return mOrderLogistics::getOrderLogistics($where, $field);
    }

    /**
     * 物流第一条固定为 商家已发货 accept——time 是发货时间
     * @param $data
     * @param $addTime
     * @return mixed
     */
    public static function addKeyToContent($data, $addTime)
    {
        array_push($data, array('accept_station' => '商家已发货', 'accept_time' => $addTime));
        return $data;
    }

    /*
     * 物流详细信息排序
     * **/
    public static function arraySort($data)
    {
        if(!empty($data)) {
            $countData = count($data);
            for ($i = 0; $i < $countData; $i++) {
                for ($j = $i + 1; $j < $countData; $j++) {
                    if (strtotime($data[$i]['accept_time']) < strtotime($data[$j]['accept_time'])) {
                        $tmp = $data[$i];
                        $data[$i] = $data[$j];
                        $data[$j] = $tmp;
                    }
                }
            }
        }

        return $data;
    }

    /*
     * 排序最新的动态
     * **/
    private static function multiSort($data)
    {
        $countData = count($data);
        foreach ($data as $k => $v) {
            for ($i = 0; $i <= $countData; $i++) {
                for ($j = $i + 1; $j < $countData; $j++) {
                    if ($data[$i]['0']['accept_time'] < $data[$j]['0']['accept_time']) {
                        $tmp = $data[$i];
                        $data[$i] = $data[$j];
                        $data[$j] = $tmp;
                    }
                }
            }
        }

        return $data;
    }
}